module elevator (CLK,RESET,error,up,down,button,delay,overweight,
advance,P,open,FLOOR,flag,UP,DOWN,BUTTON,UP_DOWN,tmp);
 input CLK,RESET;
 input error;
 input delay;
 input overweight;
 input advance;
 input [6:1] up,down,button;
 output reg [6:1] UP,DOWN,BUTTON;
 reg [3:0] POSITION;
 output reg [3:0] P;
 output reg open;
 output reg [6:1] FLOOR;
 output reg flag;
 output reg UP_DOWN;
 output reg tmp;
 integer temp;
 reg [8:0] CurrentState,NextState;
 parameter S0=9'b000000001,S1=9'b000000010,S2=9'b000000100,S3=9'b000001000,S4=9'b000010000,S5=9'b000100000,S6=9'b001000000,S7=9'b010000000,S8=9'b100000000;

 always @ (posedge CLK or negedge RESET or posedge error)
 begin
  if(~RESET|error) CurrentState<=S0;
  else CurrentState<=NextState;
 end

 always @ (RESET or CurrentState or UP_DOWN or UP or DOWN or BUTTON or P or flag or up or down or button or delay or overweight or advance)
 begin
  if(~RESET)
  begin
  UP[6:1]=6'b0;
  DOWN[6:1]=6'b0;
  BUTTON[6:1]=6'b0;
   UP_DOWN=0;
   FLOOR=6'b0;
   P=4'b0001;
   flag=0;
   open=0;
	tmp=0;
  end
  else
   begin
    if(up>UP) UP=up;
    if(down>DOWN) DOWN=down;
    if(button>BUTTON) BUTTON=button;

   if(flag==0) 
   begin
    FLOOR=UP_DOWN?DOWN|BUTTON:UP|BUTTON;
   end

   case(CurrentState)
    S0:
    begin
    open=0;
    POSITION=P;
      begin
       if(UP_DOWN==0)
        begin
         if(P==4'b0110) 
         begin
         UP_DOWN=1;
         end
         else
          begin
           case(P)
            4'b0001:
             tmp=FLOOR[2] | FLOOR[3] | FLOOR[4] | FLOOR[5] | FLOOR[6];
            4'b0010:
             tmp=FLOOR[3] | FLOOR[4] | FLOOR[5] | FLOOR[6] ;
            4'b0011:
             tmp=FLOOR[4] | FLOOR[5] | FLOOR[6];
            4'b0100:
             tmp=FLOOR[5] | FLOOR[6] ;
            4'b0101:
             tmp=FLOOR[6] ;    
           endcase
           if(tmp==0)
            begin
             FLOOR=DOWN|BUTTON;
             case(P)
            4'b0001:
             tmp=FLOOR[2] | FLOOR[3] | FLOOR[4] | FLOOR[5] | FLOOR[6];
            4'b0010:
             tmp=FLOOR[3] | FLOOR[4] | FLOOR[5] | FLOOR[6] ;
            4'b0011:
             tmp=FLOOR[4] | FLOOR[5] | FLOOR[6];
            4'b0100:
             tmp=FLOOR[5] | FLOOR[6] ;
            4'b0101:
             tmp=FLOOR[6] ;         
             endcase
             if(tmp==0) UP_DOWN=1;
             else 
              begin
               flag=1;
               UP_DOWN=0;            
              end
            end
          end
        end

       else //down
        begin
         if(P==4'b0001) 
         begin
         UP_DOWN=0;
         end
         else
          begin
           case(P)
            4'b0110:
             tmp=FLOOR[5] | FLOOR[4] | FLOOR[3] | FLOOR[2] | FLOOR[1];
            4'b0101:
             tmp=FLOOR[4] | FLOOR[3] | FLOOR[2] | FLOOR[1];
            4'b0100:
             tmp=FLOOR[3] | FLOOR[2] | FLOOR[1];
            4'b0011:
             tmp=FLOOR[2] | FLOOR[1];
            4'b0010:
             tmp=FLOOR[1];           
           endcase
           if(tmp==0)
            begin
             FLOOR=UP|BUTTON;
             case(P)
            4'b0110:
             tmp=FLOOR[5] | FLOOR[4] | FLOOR[3] | FLOOR[2] | FLOOR[1];
            4'b0101:
             tmp=FLOOR[4] | FLOOR[3] | FLOOR[2] | FLOOR[1];
            4'b0100:
             tmp=FLOOR[3] | FLOOR[2] | FLOOR[1];
            4'b0011:
             tmp=FLOOR[2] | FLOOR[1];
            4'b0010:
             tmp=FLOOR[1];            
             endcase
             if(tmp==0) UP_DOWN=0;
             else 
              begin
               flag=1;
               UP_DOWN=1;              
              end
            end
          end
        end

        begin
          if(FLOOR==6'b0) NextState=S1;
          else if(UP_DOWN==0) NextState=S5;
          else NextState=S6;
        end

      end
    end
    S1:
	 begin
	   if(advance) NextState=S0;
     else if(delay) NextState=S1;
     else NextState=S2;
	 end
    S2:
	 begin
    if(advance) NextState=S0;
     else if(delay|overweight) NextState=S1;
     else NextState=S3;
	 end
    S3:
	 begin
    if(advance) NextState=S0;
     else if(delay|overweight) NextState=S1;
    else NextState=S4;
	 end
    S4:
    begin
    if(delay|overweight) NextState=S1;
	  else NextState=S0;
    end
    S5:
    begin
     if(FLOOR==6'b0) NextState=S1;
     else
      begin
       P=P+1'b1;
       if(flag==1)
        begin: B1
         integer i;
         temp=0;
         for(i=6;i>0 && temp==0;i=i-1)
          if(FLOOR[i]==1) temp=i;
         if(P==temp) 
          begin
            flag=0;
            UP_DOWN=1;
            DOWN[P]=0;
            UP[P]=0;
            BUTTON[P]=0;
            NextState=S1;
            open=1;
          end
          else
           NextState=S7;
        end
        else
        if(FLOOR[P]) 
          begin
            NextState=S1;
            open=1;
            UP[P]=0;
            BUTTON[P]=0;
          end 
        else NextState=S7;   
        end
      end
    S6:

    begin
     if(FLOOR==6'b0) NextState=S1;
     else
      begin
       P=P-1'b1;
       if(flag==1)
        begin: B2
         integer i;
         temp=0;
         for(i=1;i<7 && temp==0;i=i+1)
          if(FLOOR[i]==1) temp=i;
         if(P==temp) 
          begin
            flag=0;
            UP_DOWN=0;
            DOWN[P]=0;
            UP[P]=0;
            BUTTON[P]=0;
            NextState=S1;
            open=1;
          end
          else
           NextState=S8;
        end
        else
        if(FLOOR[P]) 
          begin
            NextState=S1;
            open=1;
            DOWN[P]=0;
            BUTTON[P]=0;
          end 
        else NextState=S8;   
        end
    end
    S7:
     NextState=S5;
    S8:
     NextState=S6;
   endcase
  end
 end
endmodule
